import base64
import hashlib
from typing import Protocol
from .schemas import DigestResult

HASH_PER_SIZE: int = 128 * 1024


class AsyncFileObj(Protocol):
    async def read(self, size: int = -1) -> bytes:
        ...

    async def seek(self, offset: int) -> None:
        ...

    async def write(self, data: bytes) -> None:
        ...

    async def close(self) -> None:
        ...


async def digest(fr: AsyncFileObj) -> DigestResult:
    hs, hm = hashlib.sha1(), hashlib.md5()
    res = DigestResult()
    res.size = 0

    while True:
        data = await fr.read(HASH_PER_SIZE)
        if not data:
            break
        hs.update(data)
        hm.update(data)
        res.size += len(data)
        if res.size <= HASH_PER_SIZE:
            # first 128KB
            res.pre_id = hs.hexdigest().upper()

    res.quick_id = hs.hexdigest().upper()
    res.md5 = base64.b64encode(hm.digest()).decode('utf-8')
    await fr.seek(0)

    return res


if __name__ == "__main__":
    pass
